//
//  PMConstraint.m
//  PezMonkey
//
//  Created by Spence DiNicolantonio on 10/30/09.
//  Copyright 2009 Necrosoft. All rights reserved.
//

/**
 * A rigid body constraint. PMConstraint are used to connect two PMBodys.
 * This class should never be instantiated directly, rather, PMConstraint should 
 * be instantiated using one of its subclasses.
 */
 
#import "PMConstraint.h"


@implementation PMConstraint

@synthesize bodyA;
@synthesize bodyB;
@synthesize data;


#pragma mark -
#pragma mark Dealloc

/**
 * Releases member objects and frees memory used for cpConstraint before deallocating.
 */
- (void)dealloc {
	[self.bodyA release];
	[self.bodyB release];
	cpConstraintFree(constraint);
	[super dealloc];
}


#pragma mark -
#pragma mark Getters

/**
 * Returns the receiver's cpConstraint reference. This is not intended for external use.
 */
- (cpConstraint *)cpConstraint {
	return constraint;
}

/**
 * Returns the receiver's referenced rigid body corresponding to the given key.
 */
- (PMBody *)bodyForKey:(PMConstraintBodyKey)bodyKey {
	switch (bodyKey) {
		case PMConstraintBodyKeyA:
			return self.bodyA;
		case PMConstraintBodyKeyB:
			return self.bodyB;
		default:
			return nil;
	}
}

/**
 * Returns the receiver's maximum force magnitude. This is the maximum amount of 
 * force that the joint can withstand before giving out and stretching.
 */
- (PMFloat)maxForce {
	return constraint->maxForce;
}

/**
 * Returns the receiver's bias coefficient. This value defines the amount of 
 * joint error allowed. The bias coefficient will always be in the range [0,1], 
 * excluding 0.0. Larger coefficient values will result in more solid joints, but 
 * can make a simulation less stable. The default value is 0.1.
 */
- (PMFloat)biasCoef {
	return constraint->biasCoef;
}

/**
 * Returns the receiver's maximum bias.
 */
- (PMFloat)maxBias {
	return constraint->maxBias;
}


#pragma mark -
#pragma mark Setters

/**
 * Sets the receiver's maximum force magnitude to a given value. This is the 
 * maximum amount of force that the joint can withstand before giving out and 
 * stretching.
 */
- (void)setMaxForce:(PMFloat)maxForce {
	constraint->maxForce = maxForce;
}

/**
 * Sets the receiver's biasCoefficient to a given value. This value defines the 
 * amount of joint error allowed. A larger bias coefficient will result in more 
 * solid joints, but can make a simulation less stable. The given value must be 
 * in the range [0,1], excluding 0.0. If not, it will be clamped to an acceptable 
 * value. The default bias coefficient is 0.1.
 */
- (void)setBiasCoef:(PMFloat)biasCoefficient {
	constraint->biasCoef = PMFloatClamp(biasCoefficient, 
										PMFloatNext(0.0, 1.0), 1.0);
}

/**
 * Sets the receiver's maximum bias to a given value.
 */
- (void)setMaxBias:(PMFloat)maxBias {
	constraint->maxBias = maxBias;
}

/**
 * Sets the receiver's referenced rigid body corresponding to a given key, to a
 * given PMBody object.
 */
- (void)setBody:(PMBody *)body ForKey:(PMConstraintBodyKey)bodyKey {
	switch (bodyKey) {
		case PMConstraintBodyKeyA:
			self.bodyA = body;
		case PMConstraintBodyKeyB:
			self.bodyB = body;
	}
}

@end
